package com.renge.netty;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

/**
 * _*_ coding : utf-8 _*_
 *
 * @Time : 2023/8/5 21:08
 * @Author : 计201任思伟
 * @File : AppServer
 * @Project : renge_rpc
 */
public class AppServer {
    //绑定端口
    private int port;

    public AppServer(int port) {
        this.port = port;
    }

    public void start(){
        //1.创建enentloop Netty的Reactor线程池，初始化了一个NioEventLoop数组，用来处理I/O操作,如接受新的连接和读/写数据
        //老板只负责处理请求，之后会将请求分发至worker
        //默认比例1：5
        EventLoopGroup boss=new NioEventLoopGroup(2);
        EventLoopGroup worker=new NioEventLoopGroup(2);
        try {
            //2.需要服务器引导程序
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            //3.进行对服务器的配置
            serverBootstrap = serverBootstrap.group(boss, worker)
                    .channel(NioServerSocketChannel.class)//通过工厂方法设计模式实例化一个channel
                    .childHandler(new ChannelInitializer<SocketChannel>() {//入栈请求  处理入栈请求
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            //配置childHandler来通知一个关于消息处理的InfoServerHandler实例
                            socketChannel.pipeline().addLast(new MyChannelHandler());

                        }
                    });
            //4,绑定端口
            ChannelFuture channelFuture = serverBootstrap.bind(port).sync();
            //阻塞接收相关信息
            // 阻塞操作，closeFuture()开启了一个channel的监听器（这期间channel在进行各项工作），直到链路断开
            //closeFuture().sync()会阻塞当前线程，直到通道关闭操作完成。这可以用于确保在关闭通道之前，程序不会提前退出。
            channelFuture.channel().closeFuture().sync();
        }catch (InterruptedException e){
            e.printStackTrace();
        }finally {
            //优雅关闭
            try {
                boss.shutdownGracefully().sync();
                worker.shutdownGracefully().sync();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }

    public static void main(String[] args) {
        new AppServer(8088).start();
    }
}
